﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml;
using System.IO;

namespace GpxTool
{
    /// <summary>
    /// Логика взаимодействия для MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        GpxFormat gpxFile;

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            // Create OpenFileDialog
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();

            // Set filter for file extension and default file extension
            dlg.DefaultExt = ".gpx";
            dlg.Filter = "Garmin file (.gpx)|*.gpx";

            // Display OpenFileDialog by calling ShowDialog method
            Nullable<bool> result = dlg.ShowDialog();

            // Get the selected file name and display in a TextBox
            if (result == true)
            {
                gpxFile = new GpxFormat();

                #region ReadFile
                string filename = dlg.FileName;
                XmlTextReader reader = new XmlTextReader(filename);
                bool isXMLgpx = false;
                bool isXMLmetadata = false;
                bool isXMLlink = false;
                bool isXMLlinktext = false;
                bool isXMLtime = false;

                bool isXMLtrk = false;
                bool isXMLname = false;
                bool isXMLtrkseg = false;

                bool isXMLtrkpt = false;
                bool isXMLele = false;

                Track trk = new Track();
                TrackSeg trkseg = new TrackSeg();
                TrackPoint trkpt = new TrackPoint();


                #region while (reader.Read())
                while (reader.Read())
                {
                    #region XmlNodeType.Element
                    if (reader.NodeType == XmlNodeType.Element) //Если элемент
                    {
                        #region gpx
                        if (reader.Name == "gpx")
                        {
                            isXMLgpx = true;
                            gpxFile.creator = reader.GetAttribute("creator");
                            //continue;
                        }
                        #endregion
                        #region metadata
                        if (isXMLgpx && reader.Name == "metadata")
                        {
                            isXMLmetadata = true;
                        }
                        #endregion
                        #region link
                        if (isXMLgpx && isXMLmetadata && reader.Name == "link")
                        {
                            isXMLlink = true;
                            gpxFile.creator = reader.GetAttribute("href");
                        }
                        #endregion
                        #region linktext
                        if (isXMLgpx && isXMLlink && reader.Name == "text")
                        {
                            isXMLlinktext = true;
                        }
                        #endregion
                        #region time
                        if (reader.Name == "time")
                        {
                            isXMLtime = true;
                        }
                        #endregion
                        #region trk
                        if (reader.Name == "trk")
                        {
                            isXMLtrk = true;
                            trk = new Track();
                        }
                        #endregion
                        #region name
                        if (reader.Name == "name")
                        {
                            isXMLname = true;
                        }
                        #endregion
                        #region trkseg
                        if (reader.Name == "trkseg")
                        {
                            isXMLtrkseg = true;
                            trkseg = new TrackSeg();
                        }
                        #endregion
                        #region trkpt
                        if (reader.Name == "trkpt")
                        {
                            isXMLtrkpt = true;
                            trkpt = new TrackPoint();

                            trkpt.lat = GpsTool.StrToDouble( reader.GetAttribute("lat"));
                            trkpt.lon = GpsTool.StrToDouble(reader.GetAttribute("lon"));
                        }
                        #endregion
                        #region ele
                        if (reader.Name == "ele")
                        {
                            isXMLele = true;
                        }
                        #endregion
                    }
                    #endregion XmlNodeType.Element

                    #region XmlNodeType.Text
                    if (reader.NodeType == XmlNodeType.Text) //Если Text
                    {
                        #region linktext
                        if (isXMLgpx && isXMLlinktext)
                        {
                            string value = reader.Value;
                            gpxFile.linkText = value;
                        }
                        #endregion
                        #region metadata.time
                        if (isXMLgpx && isXMLmetadata && isXMLtime)
                        {
                            string value = reader.Value;
                            gpxFile.time = value;
                        }
                        #endregion
                        #region trk.name
                        if (isXMLgpx && isXMLtrk && isXMLname)
                        {
                            string value = reader.Value;
                            trk.trackName = value;
                        }
                        #endregion
                        #region trkpt.ele
                        if (isXMLgpx && isXMLtrkpt && isXMLele)
                        {
                            string value = reader.Value;
                            trkpt.ele = GpsTool.StrToDouble(value);
                        }
                        #endregion
                        #region trkpt.time
                        if (isXMLgpx && isXMLtrkpt && isXMLtime)
                        {
                            string value = reader.Value;
                            trkpt.time = value;
                        }
                        #endregion

                    }
                    #endregion XmlNodeType.Text

                    #region XmlNodeType.EndElement
                    if (reader.NodeType == XmlNodeType.EndElement) //Если элемент
                    {
                        #region gpx
                        if (reader.Name == "gpx")
                        {
                            isXMLgpx = false;
                        }
                        #endregion
                        #region metadata
                        if (reader.Name == "metadata")
                        {
                            isXMLmetadata = false;
                        }
                        #endregion
                        #region link
                        if (reader.Name == "link")
                        {
                            isXMLlink = false;
                        }
                        #endregion                     }
                        #region linktext
                        if (isXMLlinktext && reader.Name == "text")
                        {
                            isXMLlinktext = false;
                        }
                        #endregion
                        #region time
                        if (reader.Name == "time")
                        {
                            isXMLtime = false;
                        }
                        #endregion

                        #region trk
                        if (isXMLtrk && reader.Name == "trk")
                        {
                            isXMLtrk = false;
                            gpxFile.trk.Add(trk);
                        }
                        #endregion
                        #region name
                        if (reader.Name == "name")
                        {
                            isXMLname = false;
                        }
                        #endregion
                        #region trkseg
                        if (reader.Name == "trkseg")
                        {
                            isXMLtrkseg = false;
                            trk.trkseg.Add(trkseg);
                        }
                        #endregion
                        #region trkpt
                        if (reader.Name == "trkpt")
                        {
                            isXMLtrkpt = false;
                            trkseg.trkpt.Add(trkpt);
                        }
                        #endregion
                        #region ele
                        if (reader.Name == "ele")
                        {
                            isXMLele = false;
                        }
                        #endregion
                    }
                    #endregion XmlNodeType.EndElement
                }
                #endregion while (reader.Read())
                reader.Close();

                #endregion
                lstTracks.ItemsSource = null;
                lstTracks.ItemsSource = gpxFile.trk;
                //lstTracks.DisplayMemberPath = "name";
            }

        }

        void SaveToDXF(string filename)
        {
            string dxf = "0\n" //Устанавливает начало графического примитива, входа в таблицу, или же разделителя файлов. О чем именно идет речь, указывает следующее за ним текстовое значение.
                 + "SECTION\n"
                 + "2\n"
                 + "ENTITIES\n";
            int noTrk = -1;
            foreach (Track trk in lstTracks.SelectedItems)
            {
                noTrk++;
                int noTrkSeg = -1;
                foreach (TrackSeg trkseg in trk.trkseg)
                {
                    noTrkSeg++;
                    string layer = String.Format("trk{0}seg{1}", noTrk, noTrkSeg);
                    dxf += "0\n"//Устанавливает начало графического примитива, входа в таблицу, или же разделителя файлов. О чем именно идет речь, указывает следующее за ним текстовое значение.
                        + "POLYLINE\n"//ломаная
                        + "8\n"//Имя слоя (фиксированное).
                        + layer + "\n"
                        + "66\n"//Флажок "Далее идут графические примитивы" (фиксированное).
                        + "1\n"
                        + "10\n"//Первичная координата Х (начальная точка линии или текстового графического примитива, центр окружности и т.д.).
                        + "0.0\n"
                        + "20\n"//Первичная координата Y. Значения второй координаты всегда соответствуют значениям первой координаты и следуют непосредственно за ними в файле.
                        + "0.0\n"
                        + "30\n"//Первичная координата Z. Значения третьей координаты сегда соответствуют значениям первой и второй координат и следуют непосредственно за ними в файле.
                        + "0.0\n";
                    foreach (TrackPoint trkpt in trkseg.trkpt)
                    {
                        dxf += "0\n"//Устанавливает начало графического примитива, входа в таблицу, или же разделителя файлов. О чем именно идет речь, указывает следующее за ним текстовое значение.
                        + "VERTEX\n"
                        + "8\n"//Имя слоя (фиксированное).
                        + layer + "\n"
                        + "10\n"//Первичная координата Х
                        + trkpt.lon + "\n"
                        + "20\n"//Первичная координата Y.
                        + trkpt.lat + "\n"
                        + "30\n"//Первичная координата Z.
                        + trkpt.ele + "\n";
                    }
                    dxf += "0\n"//Устанавливает начало графического примитива, входа в таблицу, или же разделителя файлов. О чем именно идет речь, указывает следующее за ним текстовое значение.
                   + "SEQEND\n";

                }
            }
            /*dxf += "0\n"//Устанавливает начало графического примитива, входа в таблицу, или же разделителя файлов. О чем именно идет речь, указывает следующее за ним текстовое значение.
                 + "SEQEND\n";*/
            dxf += "0\n"//Устанавливает начало графического примитива, входа в таблицу, или же разделителя файлов. О чем именно идет речь, указывает следующее за ним текстовое значение.
                 + "ENDSEC\n"
                 + "0\n"//Устанавливает начало графического примитива, входа в таблицу, или же разделителя файлов. О чем именно идет речь, указывает следующее за ним текстовое значение.
                 + "EOF\n";

            System.IO.File.WriteAllText(filename, dxf);
        }

        void SaveToMaxScript(string filename)
        {
            string msfile = @"-- GenByWebPiket3 at " + DateTime.Now.ToString()+"\n";

            int noTrk = -1;
            double k = 1.7;
            foreach (Track trk in lstTracks.SelectedItems)
            {
                noTrk++;
                int noTrkSeg = -1;
                PointF startPnt = new PointF();
                foreach (TrackSeg trkseg in trk.trkseg)
                {
                    noTrkSeg++;
                    string layer = String.Format("Trk{0}Seg{1}", noTrk, noTrkSeg);
                    msfile += msfile = "fn Draw" + layer + " no  = \n"
                        + "(\n";

                    bool isFirstIter = true;
                    foreach (TrackPoint trkpt in trkseg.trkpt)
                    {
                        PointF pnt = new PointF();
                        pnt = GpsTool.GPSToPixelXY(trkpt.lat, trkpt.lon);
                        pnt.Z = trkpt.ele;
                        if (isFirstIter)
                        {
                            startPnt = new PointF() { X = pnt.X, Y = pnt.Y, Z = pnt.Z };
                            isFirstIter = false;
                            msfile += String.Format("\tss = SplineShape pos: [{0},{1},{2}] \n \taddNewSpline ss \n", GpsTool.DoubleToStr((pnt.X - startPnt.X) * k * 100), GpsTool.DoubleToStr((pnt.Y - startPnt.Y) * k * 100), GpsTool.DoubleToStr(pnt.Z));
                        }
                        msfile += String.Format("\taddKnot ss 1 #corner #line [{0},{1},{2}]\n", GpsTool.DoubleToStr((pnt.X - startPnt.X) * k * 100), GpsTool.DoubleToStr((pnt.Y - startPnt.Y) * k * 100), GpsTool.DoubleToStr(pnt.Z));
                    }
                    msfile += "\tupdateShape ss \n \tss \n ) \n";
                    msfile += String.Format("newSpline = Draw{0} {1}\n", layer, noTrkSeg);
                }
            }

            System.IO.File.WriteAllText(filename, msfile);
        }

        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            // Create OpenFileDialog
            Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();

            // Set filter for file extension and default file extension
            dlg.DefaultExt = ".ms";
            dlg.Filter = "3D Max Script (.ms)|*.ms|2D DXF (.dxf)|*.dxf";

            // Display OpenFileDialog by calling ShowDialog method
            Nullable<bool> result = dlg.ShowDialog();

            // Get the selected file name and display in a TextBox
            if (result == true)
            {
                string filename = dlg.FileName;
                if (dlg.FilterIndex == 1)
                    SaveToMaxScript(filename);
                if (dlg.FilterIndex == 0)
                    SaveToDXF(filename);
            }
        }
    }
}